<?php
/**
 * etframework
 * アクセス制御クラス
 * 
 * @package etframework
 */
class Access
{
    /** アクセスレベルパラメータ */
    const
        GUEST      = 0,
        MEMBER     = 10,
        MODERATOR  = 100,
        MASTER     = 1000;

    /** ユーザー */
    public $user;

    /** etworｋ用GET */
    protected $EX_GET = array();
    
    /** etworｋ用POST */
    protected $EX_POST = array();

    protected
        $isEdit = false,
        $isAuthorized = true,
        $limitLevel = self::GUEST,
        $pathParameters = array(),
        $pathScript,
        $jumpTo,
        $jumpToNew;

    function __construct()
    {
        $this->user = new User;
    }

    function __get($prop)
    {
        if (!property_exists($this,$prop)) {
            throw new InvalidArgumentException($prop.'は存在しません');
        }
        
        return $this->$prop;
    }

    function __set($prop, $val)
    {
        if (!property_exists($this,$prop)) {
            throw new InvalidArgumentException($prop.'はセットできません');
        }
        
        //アクセスレベル
        if ($prop == 'limitLevel' && $val > static::GUEST) {
            $this->isAuthorized = ($this->user->level >= $val);
        }
        
        $this->$prop = $val;
    }


    /**
     * 認証確認
     */
    public function isAuthorized()
    {
        return $this->isAuthorized;
    }

    /**
     * ログイン確認
     */
    public function isLogin()
    {
        return $this->user->level;
    }

    /**
     * ユーザーID取得
     */
    public function getUserId()
    {
        return 1;
        return $this->user->id;
    }

    /**
     * URL整形
     * @param string $scriptPath ルートディレクトリからスクリプト名までのパス
     * @param integer $depth スクリプト下に許可するディレクトリの深さ
     */
    public function parseURL ($scriptName, $depth)
    {
        $path_array = explode('/',@$_SERVER['PATH_INFO']);
        array_shift($path_array);
        $query = (@$_SERVER['QUERY_STRING']) ? '?'.$_SERVER['QUERY_STRING'] : '';
        
        $array = array();
        $needJump = false;
        
        //空のパラメータ確認
        foreach ($path_array as $v) {
            if (empty($v) && !isZero($v)) {
                $needJump = true;
                break;
            }
            $array[] = $v;
        } 
        
        //深さ確認
        if (count($array) > $depth) $needJump = true;
        
        //不正URL時リダイレクト
        if ($needJump) {
            $url = $scriptName;
            for ($i = 0; $i < $depth; $i++) {
                if (@$array[$i]) $url .= '/'.$array[$i];
            }
            //die('jump to::'.URL_SITE.$url.$query);
            Access::jump(URL_SITE.$url.$query);
        }
        
        $this->pathParameters = $array;
        $this->pathScript = $scriptName;
    }

    /**
     * GPCサニタイズ
     */
    protected function sanitizeGPC ()
    {
        $this->EX_GET  = array_map('Access::sanitizeCharacters', $_GET);
        $this->EX_POST = array_map('Access::sanitizeCharacters', $_POST);
        
        //page
        if (isset($this->EX_GET['p'])) {
            if (!isNumber($this->EX_GET['p']) || $this->EX_GET['p'] < 0) $this->EX_GET['p'] = 0;
        }
    }

    /**
     * GPCキーリセット
     * 
     * 必要なキー以外を捨てる
     * 
     * @param array $gpc
     * @param array $useArray リセットしないキー
     */
    public function resetKeys (&$gpc, $useArray = array())
    {
        foreach ($gpc as $key => $val)
        {
            if (!in_array($key, $useArray)) {
                unset($gpc[$key]);
            }
        }
        ksort($gpc);
    }
    
    /**
     * GPC無害化
     * 
     * @str - 値
     * @e   - エンコード
     * @l   - 言語
     */
    private static function sanitizeCharacters ($str, $e = "UTF-8", $l = "Japanese")
    {
        if (is_array($str)) {
            $str = array_map('Access::sanitizeCharacters', $str);
        } else {
            mb_language($l);
            $str = mb_convert_encoding($str,$e, "auto");
            $str = htmlspecialchars($str, ENT_QUOTES)  ; //無害可処理
            $str = trim($str)                          ; //前後の空白削除
        }
        return($str);
    }

    /**
     * ジャンプ
     * nullでトップページ
     * nextMessageで次ページ遷移後のメッセージを記録
     * @param url String default URL_SITE
     * @param nextMessage string default null
     */
    static function jump($url = URL_SITE, $nextMessage = null)
    {
        if ($nextMessage) {
            @session_start();
            $_SESSION['nextMessage'] = $nextMessage;
        }
        header("Location:" . $url); 
        exit;
    }

    /**
     * ハッシュ作成
     * @param string text
     * @param boolean needTime
     * @return string
     */
    static function makeHash ($text, $needTime = false)
    {
        if ($needTime) {
            $text .= time();
        }
        return hash_hmac('sha256', $text, false); 
    }


}